home *** CD-ROM | disk | FTP | other *** search
/ Super PC 31 / Super PC 31 (Shareware).iso / spc / inter / speakf / fuente / des / des.c next >
Encoding:
C/C++ Source or Header  |  1995-08-05  |  13.6 KB  |  535 lines

  1. /* Sofware DES functions
  2.  * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from
  3.  * the 1977 public-domain program by Jim Gillogly
  4.  */
  5. #define NULL    0
  6.  
  7. #ifdef _M_I86
  8. #define LITTLE_ENDIAN
  9. #include <stdlib.h> 
  10. #endif
  11.  
  12. /* Tables defined in the Data Encryption Standard documents */
  13.  
  14. #ifdef PERMUTATION
  15. /* initial permutation IP */
  16. static char ip[] = {
  17.     58, 50, 42, 34, 26, 18, 10,  2,
  18.     60, 52, 44, 36, 28, 20, 12,  4,
  19.     62, 54, 46, 38, 30, 22, 14,  6,
  20.     64, 56, 48, 40, 32, 24, 16,  8,
  21.     57, 49, 41, 33, 25, 17,  9,  1,
  22.     59, 51, 43, 35, 27, 19, 11,  3,
  23.     61, 53, 45, 37, 29, 21, 13,  5,
  24.     63, 55, 47, 39, 31, 23, 15,  7
  25. };
  26.  
  27. /* final permutation IP^-1 */
  28. static char fp[] = {
  29.     40,  8, 48, 16, 56, 24, 64, 32,
  30.     39,  7, 47, 15, 55, 23, 63, 31,
  31.     38,  6, 46, 14, 54, 22, 62, 30,
  32.     37,  5, 45, 13, 53, 21, 61, 29,
  33.     36,  4, 44, 12, 52, 20, 60, 28,
  34.     35,  3, 43, 11, 51, 19, 59, 27,
  35.     34,  2, 42, 10, 50, 18, 58, 26,
  36.     33,  1, 41,  9, 49, 17, 57, 25
  37. };
  38. #endif
  39.  
  40. /* expansion operation matrix
  41.  * This is for reference only; it is unused in the code
  42.  * as the f() function performs it implicitly for speed
  43.  */
  44. #ifdef notdef
  45. static char ei[] = {
  46.     32,  1,  2,  3,  4,  5,
  47.      4,  5,  6,  7,  8,  9,
  48.      8,  9, 10, 11, 12, 13,
  49.     12, 13, 14, 15, 16, 17,
  50.     16, 17, 18, 19, 20, 21,
  51.     20, 21, 22, 23, 24, 25,
  52.     24, 25, 26, 27, 28, 29,
  53.     28, 29, 30, 31, 32,  1 
  54. };
  55. #endif
  56.  
  57. /* permuted choice table (key) */
  58. static char pc1[] = {
  59.     57, 49, 41, 33, 25, 17,  9,
  60.      1, 58, 50, 42, 34, 26, 18,
  61.     10,  2, 59, 51, 43, 35, 27,
  62.     19, 11,  3, 60, 52, 44, 36,
  63.  
  64.     63, 55, 47, 39, 31, 23, 15,
  65.      7, 62, 54, 46, 38, 30, 22,
  66.     14,  6, 61, 53, 45, 37, 29,
  67.     21, 13,  5, 28, 20, 12,  4
  68. };
  69.  
  70. /* number left rotations of pc1 */
  71. static char totrot[] = {
  72.     1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
  73. };
  74.  
  75. /* permuted choice key (table) */
  76. static char pc2[] = {
  77.     14, 17, 11, 24,  1,  5,
  78.      3, 28, 15,  6, 21, 10,
  79.     23, 19, 12,  4, 26,  8,
  80.     16,  7, 27, 20, 13,  2,
  81.     41, 52, 31, 37, 47, 55,
  82.     30, 40, 51, 45, 33, 48,
  83.     44, 49, 39, 56, 34, 53,
  84.     46, 42, 50, 36, 29, 32
  85. };
  86.  
  87. /* The (in)famous S-boxes */
  88. static char si[8][64] = {
  89.     /* S1 */
  90.     14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
  91.      0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
  92.      4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
  93.     15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
  94.  
  95.     /* S2 */
  96.     15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
  97.      3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
  98.      0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
  99.     13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
  100.  
  101.     /* S3 */
  102.     10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
  103.     13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
  104.     13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
  105.      1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
  106.  
  107.     /* S4 */
  108.      7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
  109.     13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
  110.     10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
  111.      3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
  112.  
  113.     /* S5 */
  114.      2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
  115.     14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
  116.      4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
  117.     11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
  118.  
  119.     /* S6 */
  120.     12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
  121.     10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
  122.      9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
  123.      4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
  124.  
  125.     /* S7 */
  126.      4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
  127.     13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
  128.      1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
  129.      6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
  130.  
  131.     /* S8 */
  132.     13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
  133.      1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
  134.      7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
  135.      2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
  136. };
  137.  
  138. /* 32-bit permutation function P used on the output of the S-boxes */
  139. static char p32i[] = {    
  140.     16,  7, 20, 21,
  141.     29, 12, 28, 17,
  142.      1, 15, 23, 26,
  143.      5, 18, 31, 10,
  144.      2,  8, 24, 14,
  145.     32, 27,  3,  9,
  146.     19, 13, 30,  6,
  147.     22, 11,  4, 25
  148. };
  149. /* End of DES-defined tables */
  150.  
  151. /* Lookup tables initialized once only at startup by desinit() */
  152. static long (*sp_)[64];     /* Combined S and P boxes */
  153.  
  154. #ifdef PERMUTATION
  155. static char (*iperm)[16][8];    /* Initial and final permutations */
  156. static char (*fperm)[16][8];
  157. #else
  158. #define iperm 0
  159. #define fperm 0
  160. #endif
  161.  
  162. /* 8 6-bit subkeys for each of 16 rounds, initialized by setkey() */
  163. static unsigned char (*kn)[8];
  164.  
  165. /* bit 0 is left-most in byte */
  166. static int bytebit[] = {
  167.     0200,0100,040,020,010,04,02,01
  168. };
  169.  
  170. static int nibblebit[] = {
  171.      010,04,02,01
  172. };
  173. static int desmode;
  174.  
  175. #ifdef    LITTLE_ENDIAN 
  176.  
  177. /* Byte swap a long */
  178.  
  179. static
  180. unsigned long
  181. byteswap(unsigned long x)
  182. {
  183.     register char *cp,tmp;
  184.  
  185.     cp = (char *)&x;
  186.     tmp = cp[3];
  187.     cp[3] = cp[0];
  188.     cp[0] = tmp;
  189.  
  190.     tmp = cp[2];
  191.     cp[2] = cp[1];
  192.     cp[1] = tmp;
  193.  
  194.     return x;
  195. }
  196. #endif
  197.  
  198. #ifdef PERMUTATION
  199. /* initialize a perm array */
  200. static
  201. void perminit(perm,p)
  202. char perm[16][16][8];            /* 64-bit, either init or final */
  203. char p[64];
  204. {
  205.     register int l, j, k;
  206.     int i,m;
  207.  
  208.     /* Clear the permutation array */
  209.     for (i=0; i<16; i++)
  210.         for (j=0; j<16; j++)
  211.             for (k=0; k<8; k++)
  212.                 perm[i][j][k]=0;
  213.  
  214.     for (i=0; i<16; i++)        /* each input nibble position */
  215.         for (j = 0; j < 16; j++)/* each possible input nibble */
  216.         for (k = 0; k < 64; k++)/* each output bit position */
  217.         {   l = p[k] - 1;    /* where does this bit come from*/
  218.             if ((l >> 2) != i)  /* does it come from input posn?*/
  219.             continue;    /* if not, bit k is 0     */
  220.             if (!(j & nibblebit[l & 3]))
  221.             continue;    /* any such bit in input? */
  222.             m = k & 07;    /* which bit is this in the byte*/
  223.             perm[i][j][k>>3] |= bytebit[m];
  224.         }
  225. }
  226. #endif
  227.  
  228. /* Initialize the lookup table for the combined S and P boxes */
  229. static void
  230. spinit()
  231. {
  232.     char pbox[32];
  233.     int p,i,s,j,rowcol;
  234.     long val;
  235.  
  236.     /* Compute pbox, the inverse of p32i.
  237.      * This is easier to work with
  238.      */
  239.     for(p=0;p<32;p++){
  240.         for(i=0;i<32;i++){
  241.             if(p32i[i]-1 == p){
  242.                 pbox[p] = i;
  243.                 break;
  244.             }
  245.         }
  246.     }
  247.     for(s = 0; s < 8; s++){         /* For each S-box */
  248.         for(i=0; i<64; i++){        /* For each possible input */
  249.             val = 0;
  250.             /* The row number is formed from the first and last
  251.              * bits; the column number is from the middle 4
  252.              */
  253.             rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf);
  254.             for(j=0;j<4;j++){    /* For each output bit */
  255.                 if(si[s][rowcol] & (8 >> j)){
  256.                  val |= 1L << (31 - pbox[4*s + j]);
  257.                 }
  258.             }
  259.             sp_[s][i] = val;
  260.  
  261. #ifdef    DEBUG
  262.                         printf("sp_[%d][%2d] = %08lx\n",s,i,sp_[s][i]);
  263. #endif
  264.         }
  265.     }
  266. }
  267.  
  268.  
  269. /* Allocate space and initialize DES lookup arrays
  270.  * mode == 0: standard Data Encryption Algorithm
  271.  * mode == 1: DEA without initial and final permutations for speed
  272.  * mode == 2: DEA without permutations and with 128-byte key (completely
  273.  *          independent subkeys for each round)
  274.  */
  275. int desinit(int mode)
  276. {
  277.     if(sp_ != NULL){
  278.         /* Already initialized */
  279.         return 0;
  280.     }
  281.     desmode = mode;
  282.     
  283.     if((sp_ = (long (*)[64])malloc(sizeof(long) * 8 * 64)) == NULL){
  284.         return -1;
  285.     }
  286.     spinit();
  287.     kn = (unsigned char (*)[8])malloc(sizeof(char) * 8 * 16);
  288.     if(kn == NULL){
  289.         free((char *)sp_);
  290.         return -1;
  291.     }
  292.     if(mode == 1 || mode == 2)    /* No permutations */
  293.         return 0;
  294.  
  295. #ifdef PERMUTATION
  296.     iperm = (char (*)[16][8])malloc(sizeof(char) * 16 * 16 * 8);
  297.     if(iperm == NULL){
  298.         free((char *)sp_);
  299.         free((char *)kn);
  300.         return -1;
  301.     }
  302.     perminit(iperm,ip);
  303.  
  304.     fperm = (char (*)[16][8])malloc(sizeof(char) * 16 * 16 * 8);
  305.     if(fperm == NULL){
  306.         free((char *)sp_);
  307.         free((char *)kn);
  308.         free((char *)iperm);
  309.         return -1;
  310.     }
  311.     perminit(fperm,fp);
  312. #endif    
  313.     
  314.     return 0;
  315. }
  316. /* Free up storage used by DES */
  317. void desdone(void)
  318. {
  319.     if(sp_ == NULL)
  320.         return; /* Already done */
  321.  
  322.     free((char *)sp_);
  323.     free((char *)kn);
  324. #ifdef PERMUTATION    
  325.     if(iperm != NULL)
  326.         free((char *)iperm);
  327.     if(fperm != NULL)
  328.         free((char *)fperm);
  329.     iperm = NULL;
  330.     fperm = NULL;
  331. #endif        
  332.  
  333.     sp_ = NULL;
  334.     kn = NULL;
  335. }
  336. /* Set key (initialize key schedule array) */
  337.  
  338. void setkey(char *key)
  339. {
  340.     char pc1m[56];        /* place to modify pc1 into */
  341.     char pcr[56];        /* place to rotate pc1 into */
  342.     register int i,j,l;
  343.     int m;
  344.  
  345.     /* In mode 2, the 128 bytes of subkey are set directly from the
  346.          * user's key, allowing him to use completely independent
  347.      * subkeys for each round. Note that the user MUST specify a
  348.      * full 128 bytes.
  349.      *
  350.      * I would like to think that this technique gives the NSA a real
  351.          * headache, but I'm not THAT naive.
  352.      */
  353.     if(desmode == 2){
  354.         for(i=0;i<16;i++)
  355.             for(j=0;j<8;j++)
  356.                 kn[i][j] = *key++;
  357.         return;
  358.     }
  359.     /* Clear key schedule */
  360.     for (i=0; i<16; i++)
  361.         for (j=0; j<8; j++)
  362.             kn[i][j]=0;
  363.  
  364.     for (j=0; j<56; j++) {        /* convert pc1 to bits of key */
  365.         l=pc1[j]-1;        /* integer bit location  */
  366.         m = l & 07;        /* find bit         */
  367.         pc1m[j]=(key[l>>3] &    /* find which key byte l is in */
  368.             bytebit[m])    /* and which bit of that byte */
  369.             ? 1 : 0;    /* and store 1-bit result */
  370.     }
  371.     for (i=0; i<16; i++) {        /* key chunk for each iteration */
  372.         for (j=0; j<56; j++)    /* rotate pc1 the right amount */
  373.             pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
  374.             /* rotate left and right halves independently */
  375.         for (j=0; j<48; j++){    /* select bits individually */
  376.             /* check bit that goes to kn[j] */
  377.             if (pcr[pc2[j]-1]){
  378.                                 /* mask it in if it's there */
  379.                 l= j % 6;
  380.                 kn[i][j/6] |= bytebit[l] >> 2;
  381.             }
  382.         }
  383.     }
  384. }
  385.  
  386.  
  387. /* Permute inblock with perm */
  388. static void
  389. permute(inblock,perm,outblock)
  390. char *inblock, *outblock;        /* result into outblock,64 bits */
  391. char perm[16][16][8];            /* 2K bytes defining perm. */
  392. {
  393.     register int i,j;
  394.     register char *ib, *ob;     /* ptr to input or output block */
  395.     register char *p, *q;
  396.  
  397.     if(perm == NULL){
  398.         /* No permutation, just copy */
  399.         for(i=8; i!=0; i--)
  400.             *outblock++ = *inblock++;
  401.         return;
  402.     }
  403.     /* Clear output block     */
  404.     for (i=8, ob = outblock; i != 0; i--)
  405.         *ob++ = 0;
  406.  
  407.     ib = inblock;
  408.     for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */
  409.         ob = outblock;
  410.         p = perm[j][(*ib >> 4) & 017];
  411.         q = perm[j + 1][*ib & 017];
  412.         for (i = 8; i != 0; i--){   /* and each output byte */
  413.             *ob++ |= *p++ | *q++;    /* OR the masks together*/
  414.         }
  415.     }
  416. }
  417. /* The nonlinear function f(r,k), the heart of DES */
  418. static
  419. long
  420. f(r,subkey)
  421. unsigned long r;        /* 32 bits */
  422. unsigned char subkey[8];    /* 48-bit key for this round */
  423. {
  424.     register unsigned long rval,rt;
  425. #ifdef    TRACE
  426.     unsigned char *cp;
  427.     int i;
  428.  
  429.         printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
  430.         r,
  431.         subkey[0], subkey[1], subkey[2],
  432.         subkey[3], subkey[4], subkey[5],
  433.         subkey[6], subkey[7]);
  434. #endif
  435.     /* Run E(R) ^ K through the combined S & P boxes
  436.      * This code takes advantage of a convenient regularity in
  437.      * E, namely that each group of 6 bits in E(R) feeding
  438.      * a single S-box is a contiguous segment of R.
  439.      */
  440.     rt = (r >> 1) | ((r & 1) ? 0x80000000 : 0);
  441.     rval = 0;
  442.     rval |= sp_[0][((rt >> 26) ^ *subkey++) & 0x3f];
  443.     rval |= sp_[1][((rt >> 22) ^ *subkey++) & 0x3f];
  444.     rval |= sp_[2][((rt >> 18) ^ *subkey++) & 0x3f];
  445.     rval |= sp_[3][((rt >> 14) ^ *subkey++) & 0x3f];
  446.     rval |= sp_[4][((rt >> 10) ^ *subkey++) & 0x3f];
  447.     rval |= sp_[5][((rt >> 6) ^ *subkey++) & 0x3f];
  448.     rval |= sp_[6][((rt >> 2) ^ *subkey++) & 0x3f];
  449.     rt = (r << 1) | ((r & 0x80000000) ? 1 : 0);
  450.     rval |= sp_[7][(rt ^ *subkey) & 0x3f];
  451. #ifdef    TRACE
  452.         printf(" %08lx\n",rval);
  453. #endif
  454.     return rval;
  455. }
  456.  
  457. /* Do one DES cipher round */
  458. static void
  459. round(num,block)
  460. int num;                /* i.e. the num-th one     */
  461. unsigned long *block;
  462. {
  463.     long f();
  464.  
  465.     /* The rounds are numbered from 0 to 15. On even rounds
  466.      * the right half is fed to f() and the result exclusive-ORs
  467.      * the left half; on odd rounds the reverse is done.
  468.      */
  469.     if(num & 1){
  470.         block[1] ^= f(block[0],kn[num]);
  471.     } else {
  472.         block[0] ^= f(block[1],kn[num]);
  473.     }
  474. }          
  475.  
  476. /* In-place encryption of 64-bit block */
  477.  
  478. void endes(char *block)
  479. {
  480.     register int i;
  481.     unsigned long work[2];        /* Working data storage */
  482.     long tmp;
  483.  
  484.     permute(block,iperm,(char *)work);    /* Initial Permutation */
  485. #ifdef LITTLE_ENDIAN
  486.     work[0] = byteswap(work[0]);
  487.     work[1] = byteswap(work[1]);
  488. #endif
  489.  
  490.     /* Do the 16 rounds */
  491.     for (i=0; i<16; i++)
  492.         round(i,work);
  493.  
  494.     /* Left/right half swap */
  495.     tmp = work[0];
  496.     work[0] = work[1];    
  497.     work[1] = tmp;
  498.  
  499. #ifdef LITTLE_ENDIAN
  500.     work[0] = byteswap(work[0]);
  501.     work[1] = byteswap(work[1]);
  502. #endif
  503.     permute((char *)work,fperm,block);    /* Inverse initial permutation */
  504. }
  505. /* In-place decryption of 64-bit block */
  506. void dedes(char *block)
  507. {
  508.     register int i;
  509.     unsigned long work[2];    /* Working data storage */
  510.     long tmp;
  511.  
  512.     permute(block,iperm,(char *)work);    /* Initial permutation */
  513.  
  514. #ifdef LITTLE_ENDIAN
  515.     work[0] = byteswap(work[0]);
  516.     work[1] = byteswap(work[1]);
  517. #endif
  518.  
  519.     /* Left/right half swap */
  520.     tmp = work[0];
  521.     work[0] = work[1];    
  522.     work[1] = tmp;
  523.  
  524.     /* Do the 16 rounds in reverse order */
  525.     for (i=15; i >= 0; i--)
  526.         round(i,work);
  527.  
  528. #ifdef LITTLE_ENDIAN
  529.     work[0] = byteswap(work[0]);
  530.     work[1] = byteswap(work[1]);
  531. #endif
  532.  
  533.     permute((char *)work,fperm,block);    /* Inverse initial permutation */
  534. }
  535.